package com.ccp.dev.form.service;

import com.ccp.dev.core.basic.base.BaseService;
import com.ccp.dev.core.basic.db.datasource.JdbcTemplateUtil;
import com.ccp.dev.core.basic.page.PageBean;
import com.ccp.dev.core.basic.page.PageList;
import com.ccp.dev.core.util.StringUtil;
import com.ccp.dev.core.util.TimeUtil;
import com.ccp.dev.form.consts.FormConstants;
import com.ccp.dev.form.dao.FormQueryDao;
import com.ccp.dev.form.model.DialogField;
import com.ccp.dev.form.model.FormQuery;
import com.ccp.dev.form.util.QueryResult;
import com.ccp.dev.system.dao.SysDataSourceDao;
import com.ccp.dev.system.model.SysDataSource;
import com.ccp.dev.system.service.SysDataSourceService;
import com.ccp.dev.workflow.bpmutil.ServiceUtil;
import net.sf.json.JSONObject;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;


/**
 * 通用表单查询 service类
 *
 * @author zhaowj
 */
@Service
public class FormQueryService extends BaseService<FormQuery> {

    @Resource
    private FormQueryDao formQueryDao;

    @Resource
    private JdbcTemplateUtil jdbcTemplateUtil;

    @Resource
    private SysDataSourceDao sysDataSourceDao;

    @Value("${mybatis.configuration.database-id}")
    private String dataSourceType;

    @Resource
    private FormDialogService formDialogService;

    /**
     * 根据别名获取对话框对象。
     *
     * @param alias 别名
     * @return FormQuery对象
     */
    public FormQuery getByAlias(String alias) {
        return formQueryDao.getByAlias(alias);
    }

    /**
     * 根据 id 批量删除数据
     * @param ids ids
     */
    @Transactional(rollbackFor = Exception.class)
    public void delByIds(String[] ids){
        for(String id : ids){
            formQueryDao.delById(id);
        }
    }

    /**
     * 添加时检查别名是否唯一
     *
     * @param alias 别名
     * @return boolean
     */
    public boolean isExistAlias(String alias) {
        return formQueryDao.isExistAlias(alias) > 0;
    }

    /**
     * 更新时检查别名是否唯一
     *
     * @param alias 别名
     * @return boolean
     */
    public boolean isExistAliasForUpd(String id, String alias) {
        return formQueryDao.isExistAliasForUpd(id,alias) > 0;
    }

    /**
     * 更新自定义查询
     *
     * @param formQuery 别名
     */
    public void updatePart(FormQuery formQuery) {
        formQueryDao.updatePart(formQuery);
    }

    /**
     * 根据别名获取对应查询的数据
     *
     * @param bpmFormQuery 表单查询对象
     * @param queryData 参数
     * @param page 页码
     * @param pageSize 每页记录条数
     * @return QueryResult
     */
    public QueryResult getData(FormQuery bpmFormQuery, String queryData, Integer page, Integer pageSize)throws Exception{
        Map<String, Object> params = new HashMap<>(16);
        if (StringUtil.isNotEmpty(queryData)) {
            //修改xss过滤引起的json参数问题
            queryData = StringEscapeUtils.unescapeHtml4(queryData);
            JSONObject jsonObj = JSONObject.fromObject(queryData);
            Iterator<?> it = jsonObj.keys();
            while (it.hasNext()) {
                String key = it.next().toString();
                String value = jsonObj.getString(key);
                params.put(key, value);
            }
        }

        List<DialogField> resultList = bpmFormQuery.getReturnList();
        List<DialogField> conditionList = bpmFormQuery.getConditionList();
        String objectName = bpmFormQuery.getObjName();
        Map<String, Object> map = new HashMap<>(16);
        map.put("objectName", objectName);
        map.put("returnList", resultList);
        map.put("conditionList", conditionList);
        map.put("sortList", bpmFormQuery.getSortList());
        QueryResult queryResult = new QueryResult();
        SysDataSource sysDataSource = sysDataSourceDao.getByAlias(bpmFormQuery.getDsalias());
        String dbType = "";
        if(sysDataSource==null){
            dbType = dataSourceType;
        }else{
            dbType = sysDataSource.getDbType();
        }
        // 是否需要分页。
        if (page > 0 && pageSize > 0) {
            String sql = ServiceUtil.getSql(map, params,dbType);
            PageList pageList= jdbcTemplateUtil.getPage(bpmFormQuery.getDsalias(), page, pageSize, sql, params);
            List list =  handList(pageList);
            //查询时候解密自定义表的数据
            formDialogService.decryptCustomTableField(list, bpmFormQuery.getObjName(),false);
            queryResult.setList(list);
            queryResult.setIsPage(1);
            queryResult.setPage(page);
            queryResult.setPageSize(pageSize);
            PageBean pageBean=pageList.getPageBean();
            int totalCount = pageBean.getTotalCount();
            int totalPage = pageBean.getTotalPage();
            queryResult.setTotalCount(totalCount);
            queryResult.setTotalPage(totalPage);
        } else {
            String sql = ServiceUtil.getSql(map, params,dbType);
            List<Map<String, Object>> list=JdbcTemplateUtil.getNamedParameterJdbcTemplate(bpmFormQuery.getDsalias()).queryForList(sql, params);
            list = handList(list);
            //查询时候解密自定义表的数据
            formDialogService.decryptCustomTableField(list, bpmFormQuery.getObjName(),false);
            queryResult.setList(list);
            queryResult.setTotalCount(list.size());
        }
        return queryResult;
    }

    /**
     * 处理list
     *
     * @param list List<Map<String, Object>>
     * @return List<Map<String, Object>>
     */
    private List<Map<String, Object>> handList(List<Map<String, Object>> list) {
        List<Map<String, Object>> rtnList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> map = list.get(i);
            Map<String, Object> rtnMap = handMap(map);
            rtnList.add(rtnMap);
        }
        return rtnList;
    }

    /**
     * 处理Map
     *
     * @param map Map<String, Object>
     * @return Map<String, Object>
     */
    private Map<String, Object> handMap(Map<String, Object> map) {
        Map<String, Object> rtnMap = new HashMap<>(16);
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            // 把数据转换成小写
            String key = entry.getKey().toLowerCase();
            Object obj = entry.getValue();
            if (obj == null) {
                rtnMap.put(key, "");
                continue;
            }
            // 对时间字段单独处理。
            if (obj instanceof Date) {
                String format = FormConstants.STR_DATE_FORMAT;
                String str = TimeUtil.getDateTimeString((Date) obj, format);
                rtnMap.put(key, str);
            } else {
                rtnMap.put(key, obj);
            }
        }
        return rtnMap;
    }

    /**
     * 选择组合对话框
     * @return 组合对话框list
     */
    public List<FormQuery> getAllQueries(){
        Map<String,Object> map = new HashMap<>(16);
        return formQueryDao.queryList(map);
    }
}